package com.zwan.oam_rtc.imps;

import com.github.kevinsawicki.http.HttpRequest;
import com.zwan.oam_rtc.bean.JimpSettings;
import com.zwan.oam_rtc.bean.req.roomObservorReq;
import com.zwan.oam_rtc.constants.Const;
import com.zwan.oam_rtc.service.IVRService;
import com.zwan.oam_rtc.utils.ApplicationContextProvider;
import com.zwan.oam_rtc.utils.messages.*;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Slf4j
public class UserStatusHandler extends BasicHandler {

    public static final int STATUS_LOGINOUT = 0;
    public static final int STATUS_READY    = 1;
    public static final int STATUS_CALLING  = 2;
    public static final int STATUS_WAITING  = 3;


    private int serviceSMSKey = 63;
    private int serviceKey = 189;
    private int serviceCallKey = 168;
    private long flowid = System.currentTimeMillis();

    private static short digID = 0;

    JimpSettings jimpSettings = ApplicationContextProvider.getBean(JimpSettings.class);
    IVRService ivrService = ApplicationContextProvider.getBean(IVRService.class);

    private static Map<String, String> roomObervers = new HashMap<>();

    public static void setRoomObervers(roomObservorReq req) {
        roomObervers.put(req.getRoomprefix(), req.getCallbackurl());
    }

    public static String getRoomOberver(String room) {
        if(room == null)
            return null;

        Iterator iter = roomObervers.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry) iter.next();
            String key = (String) entry.getKey();
            if(room.startsWith(key))
                return (String) entry.getValue();
        }
        return null;
    }

    public static void printRoomOberver() {
        Iterator iter = roomObervers.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry) iter.next();
            log.info("key: " + entry.getKey());
            log.info("url: " + entry.getValue());
        }
    }


    @Override
    public void init(int pno) {
        super.init(pno);
    }


    public static void post_http(String urlStrig, String body) {
        try {
            String requestPath = urlStrig;
            URL url = new URL(requestPath);
            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
            connection.setRequestMethod("POST");
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.setRequestProperty("Connection", "Keep-Alive");
            connection.setRequestProperty("Charset", "UTF-8");
            connection.setRequestProperty("Content-type", "application/json");
            byte[] writebytes = body.getBytes();
            connection.setRequestProperty("Content-Length", String.valueOf(writebytes.length));
            OutputStream outwritestream = connection.getOutputStream();
            outwritestream.write(writebytes);
            outwritestream.flush();
            outwritestream.close();
            if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
                log.info("POST2返回错误码：" + connection.getResponseCode());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public synchronized void service(MessageHead sender, int eventid, ByteBuffer buffer, ByteOrder byteOrder) {

//        if (jimpSettings.getLog().equals("Debug"))
//        {
//                 log.info(MessageFormat.format(
//                "UserStatusHandler Recive message from {0}.{1} to {2}.{3}, eventid={4,number,#}, length={5}",
//                 JavaImp.getInstance().getModuleNo(),
//                pno, eventid, buffer.limit() - buffer.position()));
//        }


        try {
            switch (eventid) {
                case Const.EV_JANUS_CONNECTED_MESSAGE:
                {
                    ivrService.networkConnected();
                    break;
                }
                case Const.EV_JANUS_TO_OAM:    //oam主动查询的返回数据
                {
                    RtcmsResponse response = new RtcmsResponse();
                    buffer.order(byteOrder);
                    buffer.rewind();
                    response.readFromBuffer(buffer);
                    int index = response.getMsgHead().getDlgID();
                    log.info("return dlgid:" + index + " total:" + response.getTotal() + " current:" + response.getCurrent());
                    MessageWaiter waiter = this.waiters.get(index);
                    if (waiter != null) {
                        if(waiter.rtcmsResponseMerged.MergeData(response.getBody(),response.getTotal(), response.getCurrent())){
                            log.info("====service clean waiters");
                            this.waiters.remove(index);
                            waiter.setMessage(response);
                        }
                    }else {
                        ivrService.setStatus(response.getBody());
                    }
                    break;
                }
                case Const.EV_JANUS_TO_OAM_SIP_MESSAGE: {   //sip的message和subscriber事件回调
                    RtcmsResponse response = new RtcmsResponse();
                    buffer.order(byteOrder);
                    buffer.rewind();
                    response.readFromBuffer(buffer);
                    log.info("sip message:" + response.getBody());
                    break;
                }
                case Const.EV_JANUS_TO_OAM_ZWMP_MESSAGE: {   //zwmp的错误信息回调，包括各种媒体层面的异常，如断流
                    RtcmsResponse response = new RtcmsResponse();
                    buffer.order(byteOrder);
                    buffer.rewind();
                    response.readFromBuffer(buffer);
                    log.info("zwmp message:" + response.getBody());
                    break;
                }
                case Const.EV_JANUS_TO_OAM_ROOM_MESSAGE: {   //会场状态更新事件
                    RtcmsResponse response = new RtcmsResponse();
                    buffer.order(byteOrder);
                    buffer.rewind();
                    response.readFromBuffer(buffer);
                    log.info("oam room message:" + response.getBody());
                    break;
                }
                case Const.EV_JANUS_TO_IVR: {
                    RtcmsBCSM bcsm = new RtcmsBCSM();
                    buffer.order(byteOrder);
                    buffer.rewind();
                    bcsm.readFromBuffer(buffer);
                    ivrService.HandleBCSM(bcsm);
                    break;
                }
                default:
                    log.info("Unknown eventid from slp: " + eventid);
            }
        } catch (Exception e) {
            log.info("Handle message (from slp) failed" + e.getMessage());
        }
    }

    public void sendCommand(String command, String info){
        sendCommand(this.serviceKey, command, info);   //189，每个handler都有一个servicekey
    }
    public void send168Command(String command, String info){ //command"1|2"
        sendCommand(this.serviceCallKey, command, info);   //189，每个handler都有一个servicekey
    }
    public void sendSMSCommand(String command, String info){ //command"1|2"
        sendCommand(this.serviceSMSKey, command, info);   //63，每个handler都有一个servicekey
    }

    public synchronized void sendCommand(int serviceKey, String command, String info){
        log.info("Send command to SLP, type=" + command + ", command=" + info);
        CommandMessage cmd = new CommandMessage();
        cmd.setCmdType(command);
        cmd.setCommand(info);
        SLPAccessMessage req = new SLPAccessMessage();
        req.getMsgHead().setIdetifyCode("zwan");
        req.getMsgHead().setServiceKey(AccessMsgHead.NETTYPE_PARLAY, serviceKey);
        req.getMsgHead().setInitCallMode(AccessMsgHead.INITCALLMODE_CALL);
        req.getMsgHead().setIndex((short)0);
        req.getMsgHead().setType((byte)0);
        req.getMsgHead().setSourceKey(0);
        req.getMsgHead().setMsgType((byte)0);
        req.getMsgHead().setDestination(AccessMsgHead.DEST_TOSSP);
        req.getMsgHead().setNoticeMode((byte)0);
        req.getMsgHead().setCidIndex((short)0);// SDSMsgHead.getNextDlgId());
        req.setBody(cmd, JavaImp.getInstance().getByteOrder(Const.SCP_MODULE));
        //将触发业务的事件号和将info封装成SPLAcessMessage发送出去（调用BasicHandler中的sendMessage方法）
        this.sendMessage(AccessMsgHead.SEND_EVENTID, req.getByteArray(JavaImp.getInstance().getByteOrder(Const.SCP_MODULE)));
    }


    public void sendMessage2SLP(int Moduleno,int dlgID, CTIBCSMEventMessage command){

        SLPCTIMessage req = new SLPCTIMessage();
        req.getMsgHead().setIdetifyCode("zwan");
        req.getMsgHead().setServiceKey(AccessMsgHead.NETTYPE_PARLAY, this.serviceCallKey);
        req.getMsgHead().setInitCallMode(AccessMsgHead.INITCALLMODE_NONE);
        req.getMsgHead().setIndex(dlgID);
        req.getMsgHead().setType((byte)0);
        req.getMsgHead().setSourceKey(0);
        req.getMsgHead().setMsgType((byte)0);
        req.getMsgHead().setDestination((byte)0);
        req.getMsgHead().setNoticeMode((byte)0);
        req.getMsgHead().setCidIndex((short)0);//SDSMsgHead.getNextDlgId());
        req.setBody(command, JavaImp.getInstance().getByteOrder(Const.SCP_MODULE));
        log.info("sendMessage2SLP Module:"+Moduleno+" dlgno:"+dlgID+" eventid:"+req.getEventid()+" Servicekey:"+this.serviceCallKey);
        this.sendMessage(req.getEventid(), req.getByteArray(JavaImp.getInstance().getByteOrder(Const.SCP_MODULE)));
    }


    public String sendMessage2Rtcms(short id, String req, boolean waitFor){
        String rsp = null;
        RtcmsRequest rtcmsMessage = new RtcmsRequest();
        rtcmsMessage.getMsgHead().setDlgID(digID++);
        if(digID==Short.MAX_VALUE)
            digID=0;
        rtcmsMessage.setId(id);
        rtcmsMessage.setBody(req);

        if(!waitFor){
            this.sendRtcmsMessage(Const.EV_OAM_TO_JANUS, rtcmsMessage.getByteArray());
        }else {
            try {
                MessageWaiter mw = new MessageWaiter(this);
                rsp = mw.sendRtcmsMessage(Const.EV_OAM_TO_JANUS, rtcmsMessage, pno);
            }catch (Exception e){
                log.error(e.getMessage());
            }
        }
        return rsp;
    }

    public String sendIVRRequest2Rtcms(short eventid, String req, boolean waitFor){
        String rsp = null;
        RtcmsRequest rtcmsMessage = new RtcmsRequest();
        rtcmsMessage.getMsgHead().setDlgID(digID++);
        if(digID==Short.MAX_VALUE)
            digID=0;
        rtcmsMessage.setId(eventid);
        rtcmsMessage.setBody(req);

        if(!waitFor){
            this.sendRtcmsMessage(Const.EV_IVR_TO_JANUS, rtcmsMessage.getByteArray());
        }else {
            try {
                MessageWaiter mw = new MessageWaiter(this);
                rsp = mw.sendRtcmsMessage(Const.EV_IVR_TO_JANUS, rtcmsMessage, pno);
            }catch (Exception e){
                log.error(e.getMessage());
            }
        }
        return rsp;
    }
}
